#include "StdAfx.h"
#include"Storage.h"
#include"Executor.h"

using namespace std;

//enum Storage::COMMAND_TYPE;
//enum Storage::KEYWORD_TYPE;

const string Storage::KEYWORD_DATE = " -date ";
const string Storage::KEYWORD_STARTS = " -starts ";
const string Storage::KEYWORD_ENDS = " -ends ";
const string Storage::KEYWORD_DETAIL = " -detail ";
const string Storage::KEYWORD_IMPT = " -impt ";
const string Storage::KEYWORD_DONE = " -done ";

void Storage::storeResult(vector<Task *> tasklist){
	fstream storeFile,logFile;
	storeFile.open("tasker.txt",ios::out);
	logFile.open("log.txt",ios::app);
	//storeFile<<endl;
	logFile<<endl;
	for(int i=0;i<tasklist.size();i++){
	
		if(i>0) storeFile << endl;
		storeFile<<tasklist[i]->getName()
			<<" -date "
			<<tasklist[i]->getDate()
			<<" -starts "
			<<tasklist[i]->getStartTime()
			<<" -ends "
			<<tasklist[i]->getEndTime()
			<<" -detail "
			<<tasklist[i]->getDetail()
			<<  KEYWORD_IMPT
			<<tasklist[i]->getImpt()
			<< KEYWORD_DONE
			<<tasklist[i]->getDone();

		if(i>0) logFile << endl;
		logFile<<tasklist[i]->getName()
			<<" -date "
			<<tasklist[i]->getDate()
			<<" -starts "
			<<tasklist[i]->getStartTime()
			<<" -ends "
			<<tasklist[i]->getEndTime()
			<<" -detail "
			<<tasklist[i]->getDetail()
			<<KEYWORD_IMPT
			<<tasklist[i]->getImpt()
			<<KEYWORD_DONE
			<<tasklist[i]->getDone();

	}
	storeFile.close();
	logFile.close();

}


void Storage::undo(){
	char buf[MAX_ARRAY][MAX_ARRAY];
	int start=0;
	int end=0;


	fstream storeFile("tasker.txt"),logFile;
	logFile.open("log.txt",ios::in);
	int i=0;
	while(!logFile.eof()){
		logFile.getline(buf[i++],MAX_ARRAY);
	}
	int j=0;
	i=i-1;
	while(j<i){
		if(strlen(buf[j++])==0){
			start=end;
			end=j-1;;
		}
	}
	for(int k=start+1;k<end;k++){
		storeFile<<buf[k]<<endl;
	}
	storeFile.close();
	logFile.close();
	fstream logFileMo("log.txt",ios::out);
	for(int k=0;k<end;k++){
		logFileMo<<buf[k]<<endl;
	}
}

void Storage::clearLog(){
	fstream clearLogFile("log.txt",ios::out);
	fstream storeFile("tasker.txt",ios::in);
	char buf[MAX_ARRAY][MAX_ARRAY];
	int i=0;
	while(!storeFile.eof())
	{
	
		storeFile.getline(buf[i++],MAX_ARRAY);
	}
	i=i-1;
	clearLogFile<<endl;
	for(int j=0;j<i;j++){
		clearLogFile<<buf[j]<<endl;
	}
	storeFile.close();
	clearLogFile.close();
	
	
	
}

#pragma region Alternate Implementation of loadVect that does not require Executor
vector<Task*> Storage::loadVectAlternate(){
	Validator checker;

	vector<Task*> tasklist;
	fstream fileStore;
	if(isEmptyTextFile("tasker.txt"))
		return tasklist;
	fileStore.open("tasker.txt",ios::in);

	string oneTask;
	string holder;
	while(!fileStore.eof()){
		getline(fileStore, oneTask);
		Task *t=new Task;
		holder = getTaskInfo(oneTask, "", KEYWORD_DATE);
		t->appendToName(holder);
		holder = getTaskInfo(oneTask, KEYWORD_DATE, KEYWORD_STARTS);
		t->setDate(holder);
		holder = getTaskInfo(oneTask, KEYWORD_STARTS, KEYWORD_ENDS);
		t->setStartTime(atoi(holder.c_str()));
		holder = getTaskInfo(oneTask, KEYWORD_ENDS, KEYWORD_DETAIL);
		t->setEndTime(atoi(holder.c_str()));
		holder = getTaskInfo(oneTask, KEYWORD_DETAIL, KEYWORD_IMPT);
		t->appendToDetail(holder);
		holder = getTaskInfo(oneTask, KEYWORD_IMPT, KEYWORD_DONE);
		t->setImpt(true);
		holder = getTaskInfo(oneTask, KEYWORD_IMPT, "");
		t->setDone((atoi(holder.c_str())==1));
		tasklist.push_back(t);
	}
	return tasklist;
}

string Storage::getTaskInfo(string& task, string infoStart, string infoEnd)
{
	int startPos = 0, endPos = 0;
	if(!infoStart.empty())
	{
		startPos = task.find(infoStart);
		if(startPos == string::npos)
			return "";
		startPos += infoStart.length();
	}
	endPos = task.rfind(infoEnd);
	if(endPos == string::npos)
		return task.substr(startPos).c_str();
	return task.substr(startPos, endPos).c_str();
}

#pragma endregion

vector<Task*> Storage::loadVect(){

	vector<Task*> tasklist;
	Executor executor;
	Validator checker;
	fstream fileStore;
	fileStore.open("tasker.txt",ios::in);

	string str;
	int i=0;
	while(!fileStore.eof()){
		getline(fileStore,str);

		string name = executor.extractFirstWord(str);
		
		Task *t=new Task;
        t->appendToName(name);
        while(!str.empty())
        {
                string followingWord =executor.extractFirstWord(str);

                if(checker.isValidKeyword(followingWord)) {
					Executor::KEYWORD_TYPE keywordType =executor.determineKeywordType(followingWord);

							
                        switch(keywordType) 
                        {
						case Executor::DATE:
							{
                                string date = executor.extractFirstWord(str);
                                        
                                t->setDate(date);
                                        
                                break;
							}
						case Executor::STARTS:
							{
								string st_time = executor.extractFirstWord(str);
										
									t->setStartTime(executor.makeInt(st_time));
                                       

                                break;
							}
						case Executor::ENDS:
							{
								string end_time = executor.extractFirstWord(str);
										
								t->setEndTime(executor.makeInt(end_time));
                                        
                                break;
							}
						case Executor::DETAIL:
							{
								do{
									string detail = executor.extractFirstWord(str);
									t->appendToDetail(detail);
										
									followingWord = executor.getFirstWord(str);
								}while(!checker.isValidKeyword(followingWord) && !str.empty());
                                break;
							}
						case Executor::IMPT:
							{
								t->setImpt(true);
                                break;
							}
						}

				}
                else 
					t->appendToName(followingWord);
		}
				     


		tasklist.push_back(t);

	}

	return tasklist;
}

inline bool Storage::isEmptyTextFile(string fileName)
{
	ifstream inputFile;
	inputFile.open(fileName, ios_base::in);
	bool isEmpty = (inputFile.peek() == ifstream::traits_type::eof());
	inputFile.close();
	return isEmpty;
}